From 0f3e4de4cba4cc12049c07a58f9229ee6c75eaa5 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Tue, 2 Aug 2005 23:13:13 +0000 Subject: [PATCH] Fix migration for SMP guests with 1 vcpu. Free/setup timer irq on suspend/restore. Only tested to localhost. Also add initial code for >1 vcpu guests. Signed-off-by: Christian Limpach --- .../arch/xen/i386/kernel/smpboot.c | 4 +++ .../arch/xen/i386/kernel/time.c | 32 ++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index f8ef335b6b..87d0d07343 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -1560,10 +1560,14 @@ static void smp_intr_exit(void) void smp_suspend(void) { + /* XXX todo: take down time and ipi's on all cpus */ + local_teardown_timer_irq(); smp_intr_exit(); } void smp_resume(void) { + /* XXX todo: restore time and ipi's on all cpus */ smp_intr_init(); + local_setup_timer_irq(); } diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c index 56f6316cc4..f64d6d1d26 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c @@ -860,6 +860,8 @@ void start_hz_timer(void) void time_suspend(void) { /* nothing */ + teardown_irq(per_cpu(timer_irq, 0), &irq_timer); + unbind_virq_from_irq(VIRQ_TIMER); } /* No locking required. We are only CPU running, and interrupts are off. */ @@ -874,10 +876,25 @@ void time_resume(void) processed_system_time = per_cpu(shadow_time, smp_processor_id()).system_timestamp; per_cpu(processed_system_time, 0) = processed_system_time; + + per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER); + (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer); } #ifdef CONFIG_SMP static char timer_name[NR_CPUS][15]; +void local_setup_timer_irq(void) +{ + int cpu = smp_processor_id(); + + if (cpu == 0) + return; + per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER); + sprintf(timer_name[cpu], "timer%d", cpu); + BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt, + SA_INTERRUPT, timer_name[cpu], NULL)); +} + void local_setup_timer(void) { int seq, cpu = smp_processor_id(); @@ -888,10 +905,17 @@ void local_setup_timer(void) per_cpu(shadow_time, cpu).system_timestamp; } while (read_seqretry(&xtime_lock, seq)); - per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER); - sprintf(timer_name[cpu], "timer%d", cpu); - BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt, - SA_INTERRUPT, timer_name[cpu], NULL)); + local_setup_timer_irq(); +} + +void local_teardown_timer_irq(void) +{ + int cpu = smp_processor_id(); + + if (cpu == 0) + return; + free_irq(per_cpu(timer_irq, cpu), NULL); + unbind_virq_from_irq(VIRQ_TIMER); } #endif -- 2.30.2